package com.example.fairplay.newfpregistration.camera;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.widget.TextView;

import com.example.fairplay.newfpregistration.ui.DistinguishFaceActivity;
import com.example.fairplay.newfpregistration.ui.FaceToManyActivity;
import com.example.fairplay.newfpregistration.ui.MainMenu;
import com.example.mylibrary.MyApp;
import com.example.mylibrary.config.Config;
import com.example.mylibrary.data.ByteImg;
import com.example.mylibrary.data.DataDao;
import com.example.mylibrary.data.StudentInfo;
import com.example.mylibrary.util.EventUtil;
import com.example.mylibrary.util.ImageUtil;
import com.example.mylibrary.util.Logger;
import com.example.mylibrary.util.ToastUtils;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import cn.com.aratek.facelib.AraFaceAuthLib;


/**
 * Created by Administrator on 2018/1/24.
 */

public class
CameraInterface implements Camera.PreviewCallback {
	private static final int MSG_SHOW_PROGRESS_DIALOG = 3;
	private static final int MSG_DISMISS_PROGRESS_DIALOG = 4;
	private Camera mCamera;
	private Camera.Parameters mParams;
	private boolean isPreviewing = false;
	private static CameraInterface mCameraInterface;
	static Activity mActivity;
	private static Context mContext;
	private static FacePicInterface inter;
	private static MyApp app;
	private Logger logger = new Logger();
	private static int mCount;
	private static ExecutorService cachedThreadPool;
	private static ExecutorService fixThreadPool;
	private ProgressDialog progressDialog;

	private boolean faceDetectFinish = true;
	private FaceDetectThread detectThread;
	private FaceView faceView;
	private int mCameraId;
	private static AraFaceAuthLib araFaceAuthLib;
	private StudentInfo studentInfo;
	private List<StudentInfo> studentInfoAll;
	private byte[] bytes;//本地数组
	private byte[] byte2;//身份证数组
	private static float faceScore;
	private FragmentCamera fragmentCamera;
	private DistinguishFaceActivity distinguishFaceActivity;
	private FaceToManyActivity faceToManyActivity;

	private CameraInterface() {
	}

	public static void setVerifyCount(int count) {
		mCount = count;
	}

	public static synchronized CameraInterface getInstance(Context context) {
		mContext = context;
		mActivity = (Activity) context;
		inter = (FacePicInterface) mActivity;
		if (mCameraInterface == null) {
			mCameraInterface = new CameraInterface();
		}
		app = MyApp.getInstance();
		cachedThreadPool = Executors.newCachedThreadPool();
		fixThreadPool = Executors.newFixedThreadPool(2);


		SharedPreferences sp = context.getSharedPreferences("data", 0);
		faceScore = sp.getFloat("faceScore", 0);
		Log.e("faceScore----->: ", faceScore + "");
		return mCameraInterface;
	}

	public void doOpenCamera(SurfaceHolder holder, int cameraId) {
		mCamera = Camera.open(cameraId);
		mCameraId = cameraId;

	}

	public void doOpenFlash() {
		try {
			mParams = mCamera.getParameters();
			mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
			mCamera.setParameters(mParams);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void doCloseFlash() {
		try {
			mParams = mCamera.getParameters();
			mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
			mCamera.setParameters(mParams);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	public void doStartPreview(SurfaceHolder holder, float previewRate) {

		if (mActivity instanceof DistinguishFaceActivity) {
			distinguishFaceActivity = (DistinguishFaceActivity) mContext;
			fragmentCamera = distinguishFaceActivity.getFragment();
		} else {
			faceToManyActivity = (FaceToManyActivity) mContext;
			fragmentCamera = faceToManyActivity.getFragment();
		}

		faceView = fragmentCamera.getFaceView();
		if (isPreviewing) {
			mCamera.stopPreview();
			return;
		}

		if (mCamera != null) {
			mParams = mCamera.getParameters();
			mParams.setPictureFormat(PixelFormat.JPEG);
			mParams.setPreviewSize(Config.WIDTH, Config.HEIGHT);
			mParams.setPictureSize(Config.WIDTH, Config.HEIGHT);
			mParams.setPreviewFrameRate(15);
			mParams.setJpegQuality(95);
			setCameraDisplayOrientation();
			List<String> focusModes = mParams.getSupportedFocusModes();
			if (focusModes.contains("continuous-video")) {
				mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
			}
			mCamera.setParameters(mParams);
			try {
				mCamera.setPreviewDisplay(holder);
				mCamera.setPreviewCallback(this);
				mCamera.startPreview();
			} catch (IOException e) {
				e.printStackTrace();
			}
			isPreviewing = true;
			mParams = mCamera.getParameters();
		}
	}

	//摄像头旋转
	private void setCameraDisplayOrientation() {
		Camera.CameraInfo info = new Camera.CameraInfo();
		Camera.getCameraInfo(mCameraId, info);
		int rotation = mActivity.getWindowManager().getDefaultDisplay()
				.getRotation();
		int degrees = 0;
		switch (rotation) {
			case Surface.ROTATION_0:
				degrees = 0;
				break;
			case Surface.ROTATION_90:
				degrees = 90;
				break;
			case Surface.ROTATION_180:
				degrees = 180;
				break;
			case Surface.ROTATION_270:
				degrees = 270;
				break;
		}

		int result;
		if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
			result = (info.orientation + degrees) % 360;
			result = (360 - result) % 360; // compensate the mirror
		} else { // back-facing
			result = (info.orientation - degrees + 360) % 360;
		}
		mCamera.setDisplayOrientation(result);
	}


	public void startPreview() {
		mCamera.startPreview();
	}

	public void stopPreview() {
		mCamera.stopPreview();
	}

	/**
	 * stop preview Camera
	 */
	public void doStopCamera() {
		if (null != mCamera) {
			mCamera.setPreviewCallback(null);
			mCamera.stopPreview();
			isPreviewing = false;
			mCamera.release();
			mCamera = null;
		}

	}

	public void doTakePicture() {
		try {
			if (isPreviewing && (mCamera != null)) {
				mCamera.takePicture(mShutterCallback, null,
						mJpegPictureCallback);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Camera.Parameters getCameraParams() {
		if (mCamera != null) {
			mParams = mCamera.getParameters();
			return mParams;
		}
		return null;
	}

	public Camera getCameraDevice() {
		return mCamera;
	}


	public AraFaceAuthLib getAraFaceAuthLib() {
		return araFaceAuthLib;
	}


	ShutterCallback mShutterCallback = new ShutterCallback() {
		public void onShutter() {
		}
	};
	PictureCallback mJpegPictureCallback = new PictureCallback() {
		public void onPictureTaken(byte[] data, Camera camera) {
			stopPreview();
			isPreviewing = false;
			progressDialog = new ProgressDialog(mActivity);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			progressDialog.setIcon(android.R.drawable.ic_dialog_info);
			progressDialog.setIndeterminate(false);
			progressDialog.setCancelable(false);
			progressDialog.setMessage("正在比对，请稍候...");
			progressDialog.setTitle("正在加载");
			progressDialog.show();
			final byte[] snapshotFeature = data;
			cachedThreadPool = Executors.newCachedThreadPool();
			cachedThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					if (mActivity instanceof DistinguishFaceActivity) {
						OffLineVerification(snapshotFeature);
					} else if (mActivity instanceof FaceToManyActivity) {
						OffLineVerification2(snapshotFeature);
					}
				}
			});
		}

	};

	/**
	 * 人证离线人脸比对
	 *
	 * @param data
	 */
	private void OffLineVerification(byte[] data) {
		araFaceAuthLib = MainMenu.getAraFaceAuthLib();
		Bitmap bmp2 = BitmapFactory.decodeByteArray(data, 0, data.length);
		Bitmap b = ImageUtil.getRotateBitmap(bmp2, Config.displayOrientation);

		byte[] SnapshotData = araFaceAuthLib.getFeature(b);

		bytes = fragmentCamera.getBytes();
		byte2 = fragmentCamera.getByte2();
		float score1 = 0;
		float score2 = 0;
		if (byte2 != null) {
			score2 = araFaceAuthLib.verify(byte2, SnapshotData);
		}
		if (bytes != null) {
			score1 = araFaceAuthLib.verify(bytes, SnapshotData);
		}
		Bundle bundle = new Bundle();
		bundle.putFloat("score1", score1);
		bundle.putFloat("score2", score2);
		bundle.putByteArray("snapshotFeature", data);
		//  handler.sendMessage(handler.obtainMessage(EventUtil.MSG_FACEVERIFY_RESULT, bundle));
		handler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);
		BackToCollection(score1, score2, data, "");
	}

	private int number = 0;

	/**
	 * 离线人脸识别比对
	 *
	 * @param data
	 */
	private void OffLineVerification2(byte[] data) {
		araFaceAuthLib = MainMenu.getAraFaceAuthLib();
		Bitmap bmp2 = BitmapFactory.decodeByteArray(data, 0, data.length);
		Bitmap b = ImageUtil.getRotateBitmap(bmp2, Config.displayOrientation);

		byte[] SnapshotData = araFaceAuthLib.getFeature(b);

//		bytes = fragmentCamera.getBytes();
//		byte2 = fragmentCamera.getByte2();
		float score1 = 0;
		float score2 = 0;
		String studentCode = "";
		List<ByteImg> allStudents = DataDao.queryImgAll();

		for (int i = 0; i < allStudents.size(); i++) {
			score1 = araFaceAuthLib.verify(allStudents.get(i).getImgFeature(), SnapshotData);
			logger.i(score1 + "-----------------");
			if (score1 != -1 && score1 != 0) {
				studentCode = allStudents.get(i).getStudentCode();
//				Bundle bundle = new Bundle();
//				bundle.putFloat("score1", score1);
//				bundle.putFloat("score2", score2);
//				bundle.putString("student", byteIma.getStudentCode());
//				bundle.putByteArray("snapshotFeature", data);
				BackToCollection(score1, score2, data, studentCode);
				break;
			} else {
				if (i == allStudents.size() - 1) {
					handler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);
					startPreview();
					isPreviewing = true;
					mCamera.setPreviewCallback(CameraInterface.this);
					faceDetectFinish = true;
					handler.sendEmptyMessage(5);
				}
			}
		}

	}

	public void changeCamera(){
		startPreview();
		isPreviewing = true;
		mCamera.setPreviewCallback(CameraInterface.this);
		faceDetectFinish = true;
	}

	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
				case 5:
					ToastUtils.Toast(mContext, "匹配不到当前人脸");
					break;
				case EventUtil.MSG_FACEVERIFY_RESULT: {
					Bundle bundle = (Bundle) msg.obj;
					float score1 = bundle.getFloat("score1");
					float score2 = bundle.getFloat("score2");
//					if (score == 0 || score == -1) {
//						if (mCount == 1) {
//							BackToCollection(score, score,bundle.getByteArray("snapshotFeature"),"");
//						} else {
//							mCount--;
//							String str;
//							if (score == 0) {
//								str = "比对失败";
//							} else {
//								str = "未检测到人脸";
//							}
//							showResultMessage(str);
//						}
//					} else {
//						BackToCollection(score, bundle.getByteArray("snapshotFeature"));
//					}
					break;
				}
				case EventUtil.UPDATE_FACE_RECT: {
					final FaceResult faceResult = (FaceResult) msg.obj;
					if (app.getPreferences().getInt(Config.KEY_SHUTTER_MODE,
							Config.MODE_AUTO) == Config.MODE_AUTO) {
						faceView.setFaces(faceResult);
						faceDetectFinish = true;
						app.faceDetectRectShowCount++;
						faceDetectFinish = true;
					   /* if (app.faceDetectRectShowCount >= 5) {
					        app.faceDetectRectShowCount = 0;
                            doTakePicture();
                        }*/
						doTakePicture();
					} else {
						break;
					}
					break;
				}
				case EventUtil.UPDATE_NO_FACE_RECT: {
					faceView.clearFaces();
					app.faceDetectRectShowCount = 0;
					faceDetectFinish = true;
					break;
				}
				case MSG_SHOW_PROGRESS_DIALOG: {
					progressDialog.setMessage("正在比对，请稍候...");
					progressDialog.setTitle("正在加载");
					progressDialog.show();
					break;
				}
				case MSG_DISMISS_PROGRESS_DIALOG: {
					progressDialog.dismiss();
					break;
				}
				default:
					break;


			}
		}

	};


	private void BackToCollection(float score1, float score2, byte[] snapshotFeature, String studentCode) {
		handler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);
		Intent intent1 = new Intent();
		intent1.putExtra("score1", score1);
		intent1.putExtra("score2", score2);
		intent1.putExtra("student", studentCode);
		intent1.putExtra("snapshotFeature", snapshotFeature);
		logger.e("snapshotFeature = " + snapshotFeature);
		fixThreadPool.shutdownNow();
		inter.fromPic(222, 1, intent1);
		if (mContext instanceof DistinguishFaceActivity) {
			// distinguishFaceActivity.getFragmentManager().popBackStack();
			distinguishFaceActivity.removeFragment();
		} else {
			faceToManyActivity.removeFragment();
		}


	}

	/**
	 * 弹出对话框并显示提示
	 *
	 * @param str
	 */
	private void showResultMessage(String str) {
		faceDetectFinish = false;
		faceView.clearFaces();
		TextView tv = new TextView(mActivity);
		tv.setText(str);
		tv.setTextSize(20);
		tv.setPadding(5, 2, 5, 2);
		tv.setGravity(Gravity.CENTER);
		tv.setTextColor(Color.rgb(255, 165, 0));
		AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
		dialog.setTitle("提示").setView(tv).setCancelable(false)
				.setPositiveButton("重拍", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
						startPreview();
						isPreviewing = true;
						mCamera.setPreviewCallback(CameraInterface.this);
						faceDetectFinish = true;
					}
				}).create().show();
	}

	/**
	 * 开始人脸识别
	 */
	private void startFaceDetect(byte[] data) {
		faceDetectFinish = false;
		detectThread = new FaceDetectThread(mContext, handler, data);
		detectThread.start();
	}


	/**
	 * 停止人脸识别
	 */
	private void stopFaceDetect() {
		detectThread = null;
		faceView.clearFaces();
		faceDetectFinish = true;
	}

	@Override
	public void onPreviewFrame(byte[] data, Camera camera) {
		if (app.getPreferences().getInt(Config.KEY_SHUTTER_MODE,
				Config.MODE_AUTO) == Config.MODE_AUTO) {
			if (faceDetectFinish) {
				startFaceDetect(data);
			}
		} else {
			stopFaceDetect();
		}
	}

}
